package com.hsmpay.mobile.ds.impl;

import com.hsmpay.common.pojo.BasePojo;
import com.hsmpay.common.pojo.qian4.Qian4SendLog;
import com.hsmpay.common.util.NumberUtil;
import com.hsmpay.mobile.dao.other.SettingsDao;
import com.hsmpay.mobile.dao.terminal.TchannelDao;
import com.hsmpay.mobile.dao.terminal.TchannelMDao;
import com.hsmpay.mobile.dao.trans.TransOrderDao;
import com.hsmpay.mobile.ds.DS_KaYinKaService;
import com.hsmpay.mobile.ds.DS_ZhongLanService;
import com.hsmpay.mobile.pojo.other.Settings;
import com.hsmpay.mobile.pojo.terminal.Tchannel;
import com.hsmpay.mobile.pojo.terminal.TchannelM;
import com.hsmpay.mobile.pojo.trans.TransOrder;
import com.hsmpay.qian4.pojo.BalanceResult;
import com.hsmpay.qian4.pojo.PurchaseResult;
import com.hsmpay.qian4.pojo.RevocationResult;
import com.hsmpay.yl8583.service.KaYinKaService;
import com.hsmpay.yl8583.service.ZhongLanService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 中岚联代收接服务类
 */
@Service("DS_KaYinKaService")
public class DS_KaYinKaServiceImpl implements DS_KaYinKaService<BasePojo,Long> {

    @Resource(name = "tchannelDao")
    TchannelDao<Tchannel, Long> tchannelDao;
    @Resource(name = "transOrderDao")
    private TransOrderDao<TransOrder, String> transOrderDao;//交易订单
    @Resource(name = "tchannelMDao")
    private TchannelMDao<TchannelM, String> tchannelMDao;//通道商户号表
    @Resource(name="settingsDao")
    private SettingsDao<Settings,Long> settingsDao;//配置表

    private Long flRoleId = 2l;
    private Long fdRoleId = 3l;
    private static int cnt = 0;
    private static int KAYINKA_CHANNELID = 65;

    /**
     * 获取中岚socket配置信息
     * @return
     * @throws Exception
     */
    public Map<String, String> getKaYinKaConfig() throws Exception{
        Settings settings = new Settings();
        settings.setFunctionKey("CHANNEL_KAYINKA_CONFIG");
        settings = settingsDao.searchEntity(settings);
        String mainValue = settings == null?null:settings.getMainValue();//ip:port
        String organizationId = settings == null?null:settings.getValue2();//机构号
        /**
         * 解析mainValue
         */
        String ip = "";
        String port = "";
        if (StringUtils.isNotBlank(mainValue)){
            String[] res2 = mainValue.split(":");
            ip = res2[0];
            port = res2[1];
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put("ip", ip);
        map.put("port", port);
        map.put("organizationId", organizationId);
        return map;
    }
    /**
     * 获取中岚银联socket 接口密钥
     *
     * @param str
     * @return
     * @throws Exception
     */
    public Map<String, String> getMiYao(TchannelM tcm, String str, String transAmt, Double c_fdMoney) throws Exception {
        Map<String, String> miYao = null;
        if (StringUtils.isEmpty(str)) {
            miYao = reflushMiYao(tcm, transAmt, c_fdMoney);
        } else {
            miYao = new HashMap<String, String>();
            String[] strA = str.split("_");
            if ("-1".equals(strA[0]) || StringUtils.isEmpty(strA[2].trim()))
                return reflushMiYao(tcm, transAmt, c_fdMoney);
            miYao.put("batchId", strA[2]);
            miYao.put("pinKey", strA[3]);
            miYao.put("macKey", strA[4]);
        }
        return miYao;
    }

    /**
     * 刷新中岚银联socket 接口密钥
     *
     * @return
     * @throws Exception
     */
    public Map<String, String> reflushMiYao(TchannelM tcm, String transAmt, Double c_fdMoney) throws Exception {
        Map<String,String> config = getKaYinKaConfig();
        KaYinKaService aps = new KaYinKaService(tcm.getMcode(), tcm.getTcode(), "000001", tcm.getMainKey(), null, null, null, config);

        Integer bankOrderNum = searchKaYinKaTransId();
        String miyao = aps.login(bankOrderNum.toString());
        //保存密钥
        tchannelMDao.updateMobileTcOtherById(tcm.getId(), miyao);
        return getMiYao(tcm, miyao, transAmt, c_fdMoney);
    }

    /**
     * 消费交易
     * @param send
     * @param tc
     * @return
     * @throws Exception
     */
    public PurchaseResult billPayment(Qian4SendLog send, Tchannel tc) throws Exception {
        Double c_fdMoney = NumberUtil.roundF2((tc.getFdMaxFee() / tc.getFeeRate()));
        TchannelM tcm = tchannelMDao.searchTchannelMByCode(send.getCollectionType(), send.getMerchantId(), send.getTerminalId());
        Map<String, String> miyao = getMiYao(tcm, tcm.getOtherParam(), send.getTransAmt(), c_fdMoney);
        Map<String,String> config = getKaYinKaConfig();
        KaYinKaService aps = new KaYinKaService(send.getMerchantId(), send.getTerminalId(), miyao.get("batchId"), tcm.getMainKey(), miyao.get("pinKey"), miyao.get("macKey"), "", config);
        PurchaseResult rs = aps.billPayment(send);
        if("00A0".equals(rs.getReqCode())){
            miyao = reflushMiYao(tcm, send.getTransAmt(),c_fdMoney);
            aps = new KaYinKaService(send.getMerchantId(), send.getTerminalId(), miyao.get("batchId"), tcm.getMainKey(), miyao.get("pinKey"), miyao.get("macKey"), "", config);
            rs = aps.billPayment(send);
        }
        return rs;
    }


    /**
     * 消费撤消
     * @param send
     * @return
     * @throws Exception
     */
    public RevocationResult unBillPayment(Qian4SendLog send) throws Exception {
        Tchannel tc = tchannelDao.searchMobileTchannelByCode(send.getCollectionType());
        Double c_fdMoney = NumberUtil.roundF2((tc.getFdMaxFee() / tc.getFeeRate()));
        TchannelM tcm = tchannelMDao.searchTchannelMByCode(send.getCollectionType(), send.getMerchantId(), send.getTerminalId());
        Map<String, String> miyao = getMiYao(tcm, tcm.getOtherParam(), send.getTransAmt(), c_fdMoney);
        Map<String,String> config = getKaYinKaConfig();
        //冲正  重新创建接口对象
        KaYinKaService aps = new KaYinKaService(send.getMerchantId(), send.getTerminalId(), miyao.get("batchId"), tcm.getMainKey(), miyao.get("pinKey"), miyao.get("macKey"), "", config);
        RevocationResult rr = aps.unBillPayment(send);
        return rr;
    }

    /**
     * 查询卡银卡交易流水号
     * @return
     * @throws Exception
     */
    public Integer searchKaYinKaTransId() throws Exception {
        return transOrderDao.searchKaYinKaTransId();
    }

    /**
     *  初始化请求参数
     * @param send
     * @param tc
     * @return
     * @throws Exception
     */
    public Qian4SendLog initSend(Qian4SendLog send, Tchannel tc) throws Exception {
        Double c_fdMoney = NumberUtil.roundF2((tc.getFdMaxFee() / tc.getFeeRate()));
        KaYinKaService aps = getKaYinKaService(send.getTransAmt(), c_fdMoney);
        send.setCollectionType(tc.getCode());
        send.setBankOrderNum(searchKaYinKaTransId().toString());//查询序列 获取动态流水号
        send.setBatchId(aps.batch);//批次号
        send.setMerchantId(aps.merchantId);
        send.setTerminalId(aps.terminalId);
        return send;
    }
    /**
     * 获得费率版支付接口
     *
     * @return
     * @throws Exception
     */
    public KaYinKaService getKaYinKaService(String transAmt, Double c_fdMoney) throws Exception {
        TchannelM tcm = getTchannelM(transAmt, c_fdMoney);

        Map<String, String> miyao = getMiYao(tcm, tcm.getOtherParam(), transAmt, c_fdMoney);
        Map<String,String> config = getKaYinKaConfig();
        //获取主密钥 和 终端号
        return new KaYinKaService(tcm.getMcode(), tcm.getTcode(), miyao.get("batchId"), tcm.getMainKey(), miyao.get("pinKey"), miyao.get("macKey"), "", config);
    }

    private TchannelM getTchannelM(String transAmt, Double c_fdMoney) throws Exception {
        TchannelM tcm = null;
        Double money = 0.00;
        if (StringUtils.isNotEmpty(transAmt)) {
            money = Integer.parseInt(transAmt) / 100.0;
        }
        Long roleId = flRoleId;
        if (money > c_fdMoney) roleId = fdRoleId;
        List<TchannelM> list = tchannelMDao.searchMobileTCListByCode(KAYINKA_CHANNELID, roleId);
        tcm = list.get(cnt % list.size());
        cnt++;
        return tcm;
    }
}
